#include "Huffman.h"

const byte* Huffman::bigLookup(int table, char x, char y) {
	x = x < 0 ? -x : x;
	y = y < 0 ? -y : y;
	byte i = (x << 4) | y;
	switch(table) {
		case 1: return bigLookup1[i];
		case 2: return bigLookup2[i];
		case 3: return bigLookup3[i];
		case 5: return bigLookup5[i];
		case 6: return bigLookup6[i];
		case 7: return bigLookup7[i];
		case 8: return bigLookup8[i];
		case 9: return bigLookup9[i];
		case 10: return bigLookup10[i];
		case 11: return bigLookup11[i];
		case 12: return bigLookup12[i];
		case 13: return bigLookup13[i];
		case 15: return bigLookup15[i];
		default: return 0;
	}
}

const byte Huffman::bigLookup1[4][2] = {
	{0x01, 1},	{0x01, 3},	{0x01, 2},	{0x00, 3}};

const byte Huffman::bigLookup2[9][2] = {
	{0x01, 1},	{0x02, 3},	{0x01, 6},	{0x03, 3},	{0x01, 3},	{0x01, 5},	{0x03, 5},	{0x02, 5},
	{0x00, 6}};

const byte Huffman::bigLookup3[9][2] = {
	{0x03, 2},	{0x02, 2},	{0x01, 6},	{0x01, 3},	{0x01, 2},	{0x01, 5},	{0x03, 5},	{0x02, 5},
	{0x00, 6}};

const byte Huffman::bigLookup5[16][2] = {
	{0x01, 1},	{0x02, 3},	{0x06, 6},	{0x05, 7},	{0x03, 3},	{0x01, 3},	{0x04, 6},	{0x04, 7},
	{0x07, 6},	{0x05, 6},	{0x07, 7},	{0x01, 8},	{0x06, 7},	{0x01, 6},	{0x01, 7},	{0x00, 8}
};

const byte Huffman::bigLookup6[16][2] = {
	{0x07, 3},	{0x03, 3},	{0x05, 5},	{0x01, 7},	{0x06, 3},	{0x02, 2},	{0x03, 4},	{0x02, 5},
	{0x05, 4},	{0x04, 4},	{0x04, 5},	{0x01, 6},	{0x03, 6},	{0x03, 5},	{0x02, 6},	{0x00, 7}
};

const byte Huffman::bigLookup7[36][2] = {
	{0x01, 1},	{0x02, 3},	{0x0A, 6},	{0x13, 8},	{0x10, 8},	{0x0A, 9},	{0x03, 3},	{0x03, 4},
	{0x07, 6},	{0x0A, 7},	{0x05, 7},	{0x03, 8},	{0x0B, 6},	{0x04, 5},	{0x0D, 7},	{0x11, 8},
	{0x08, 8},	{0x04, 9},	{0x0C, 7},	{0x0B, 7},	{0x12, 8},	{0x0F, 9},	{0x0B, 9},	{0x02, 9},
	{0x07, 7},	{0x06, 7},	{0x09, 8},	{0x0E, 9},	{0x03, 9},	{0x01, 10},	{0x06, 8},	{0x04, 8},
	{0x05, 9},	{0x03, 10},	{0x02, 10},	{0x00, 10}};

const byte Huffman::bigLookup8[36][2] = {
	{0x03, 2},	{0x04, 3},	{0x06, 6},	{0x12, 8},	{0x0C, 8},	{0x05, 9},	{0x05, 3},	{0x01, 2},
	{0x02, 4},	{0x10, 8},	{0x09, 8},	{0x03, 8},	{0x07, 6},	{0x03, 4},	{0x05, 6},	{0x0E, 8},
	{0x07, 8},	{0x03, 9},	{0x13, 8},	{0x11, 8},	{0x0F, 8},	{0x0D, 9},	{0x0A, 9},	{0x04, 10},
	{0x0D, 8},	{0x05, 7},	{0x08, 8},	{0x0B, 9},	{0x05, 10},	{0x01, 10},	{0x0C, 9},	{0x04, 8},
	{0x04, 9},	{0x01, 9},	{0x01, 11},	{0x00, 11}};

const byte Huffman::bigLookup9[36][2] = {
	{0x07, 3},	{0x05, 3},	{0x09, 5},	{0x0E, 6},	{0x0F, 8},	{0x07, 9},	{0x06, 3},	{0x04, 3},
	{0x05, 4},	{0x05, 5},	{0x06, 6},	{0x07, 8},	{0x07, 4},	{0x06, 4},	{0x08, 5},	{0x08, 6},
	{0x08, 7},	{0x05, 8},	{0x0F, 6},	{0x06, 5},	{0x09, 6},	{0x0A, 7},	{0x05, 7},	{0x01, 8},
	{0x0B, 7},	{0x07, 6},	{0x09, 7},	{0x06, 7},	{0x04, 8},	{0x01, 9},	{0x0E, 8},	{0x04, 7},
	{0x06, 8},	{0x02, 8},	{0x06, 9},	{0x00, 9}};

const byte Huffman::bigLookup10[64][2] = {
	{0x01, 1},	{0x02, 3},	{0x0A, 6},	{0x17, 8},	{0x23, 9},	{0x1E, 9},	{0x0C, 9},	{0x11, 10},
	{0x03, 3},	{0x03, 4},	{0x08, 6},	{0x0C, 7},	{0x12, 8},	{0x15, 9},	{0x0C, 8},	{0x07, 8},
	{0x0B, 6},	{0x09, 6},	{0x0F, 7},	{0x15, 8},	{0x20, 9},	{0x28, 10},	{0x13, 9},	{0x06, 9},
	{0x0E, 7},	{0x0D, 7},	{0x16, 8},	{0x22, 9},	{0x2E, 10},	{0x17, 10},	{0x12, 9},	{0x07, 10},
	{0x14, 8},	{0x13, 8},	{0x21, 9},	{0x2F, 10},	{0x1B, 10},	{0x16, 10},	{0x09, 10},	{0x03, 10},
	{0x1F, 9},	{0x16, 9},	{0x29, 10},	{0x1A, 10},	{0x15, 11},	{0x14, 11},	{0x05, 10},	{0x03, 11},
	{0x0E, 8},	{0x0D, 8},	{0x0A, 9},	{0x0B, 10},	{0x10, 10},	{0x06, 10},	{0x05, 11},	{0x01, 11},
	{0x09, 9},	{0x08, 8},	{0x07, 9},	{0x08, 10},	{0x04, 10},	{0x04, 11},	{0x02, 11},	{0x00, 11}
};

const byte Huffman::bigLookup11[64][2] = {
	{0x03, 2},	{0x04, 3},	{0x0A, 5},	{0x18, 7},	{0x22, 8},	{0x21, 9},	{0x15, 8},	{0x0F, 9},
	{0x05, 3},	{0x03, 3},	{0x04, 4},	{0x0A, 6},	{0x20, 8},	{0x11, 8},	{0x0B, 7},	{0x0A, 8},
	{0x0B, 5},	{0x07, 5},	{0x0D, 6},	{0x12, 7},	{0x1E, 8},	{0x1F, 9},	{0x14, 8},	{0x05, 8},
	{0x19, 7},	{0x0B, 6},	{0x13, 7},	{0x3B, 9},	{0x1B, 8},	{0x12, 10},	{0x0C, 8},	{0x05, 9},
	{0x23, 8},	{0x21, 8},	{0x1F, 8},	{0x3A, 9},	{0x1E, 9},	{0x10, 10},	{0x07, 9},	{0x05, 10},
	{0x1C, 8},	{0x1A, 8},	{0x20, 9},	{0x13, 10},	{0x11, 10},	{0x0F, 11},	{0x08, 10},	{0x0E, 11},
	{0x0E, 8},	{0x0C, 7},	{0x09, 7},	{0x0D, 8},	{0x0E, 9},	{0x09, 10},	{0x04, 10},	{0x01, 10},
	{0x0B, 8},	{0x04, 7},	{0x06, 8},	{0x06, 9},	{0x06, 10},	{0x03, 10},	{0x02, 10},	{0x00, 10}
};

const byte Huffman::bigLookup12[64][2] = {
	{0x09, 4},	{0x06, 3},	{0x10, 5},	{0x21, 7},	{0x29, 8},	{0x27, 9},	{0x26, 9},	{0x1A, 9},
	{0x07, 3},	{0x05, 3},	{0x06, 4},	{0x09, 5},	{0x17, 7},	{0x10, 7},	{0x1A, 8},	{0x0B, 8},
	{0x11, 5},	{0x07, 4},	{0x0B, 5},	{0x0E, 6},	{0x15, 7},	{0x1E, 8},	{0x0A, 7},	{0x07, 8},
	{0x11, 6},	{0x0A, 5},	{0x0F, 6},	{0x0C, 6},	{0x12, 7},	{0x1C, 8},	{0x0E, 8},	{0x05, 8},
	{0x20, 7},	{0x0D, 6},	{0x16, 7},	{0x13, 7},	{0x12, 8},	{0x10, 8},	{0x09, 8},	{0x05, 9},
	{0x28, 8},	{0x11, 7},	{0x1F, 8},	{0x1D, 8},	{0x11, 8},	{0x0D, 9},	{0x04, 8},	{0x02, 9},
	{0x1B, 8},	{0x0C, 7},	{0x0B, 7},	{0x0F, 8},	{0x0A, 8},	{0x07, 9},	{0x04, 9},	{0x01, 10},
	{0x1B, 9},	{0x0C, 8},	{0x08, 8},	{0x0C, 9},	{0x06, 9},	{0x03, 9},	{0x01, 9},	{0x00, 10}
};

const byte Huffman::bigLookup13[256][2] = {
	{0x01, 1},	{0x05, 4},	{0x0E, 6},	{0x15, 7},	{0x22, 8},	{0x33, 9},	{0x2E, 9},	{0x47, 10},
	{0x2A, 9},	{0x34, 10},	{0x44, 11},	{0x34, 11},	{0x43, 12},	{0x2C, 12},	{0x2B, 13},	{0x13, 13},
	{0x03, 3},	{0x04, 4},	{0x0C, 6},	{0x13, 7},	{0x1F, 8},	{0x1A, 8},	{0x2C, 9},	{0x21, 9},
	{0x1F, 9},	{0x18, 9},	{0x20, 10},	{0x18, 10},	{0x1F, 11},	{0x23, 12},	{0x16, 12},	{0x0E, 12},
	{0x0F, 6},	{0x0D, 6},	{0x17, 7},	{0x24, 8},	{0x3B, 9},	{0x31, 9},	{0x4D, 10},	{0x41, 10},
	{0x1D, 9},	{0x28, 10},	{0x1E, 10},	{0x28, 11},	{0x1B, 11},	{0x21, 12},	{0x2A, 13},	{0x10, 13},
	{0x16, 7},	{0x14, 7},	{0x25, 8},	{0x3D, 9},	{0x38, 9},	{0x4F, 10},	{0x49, 10},	{0x40, 10},
	{0x2B, 10},	{0x4C, 11},	{0x38, 11},	{0x25, 11},	{0x1A, 11},	{0x1F, 12},	{0x19, 13},	{0x0E, 13},
	{0x23, 8},	{0x10, 7},	{0x3C, 9},	{0x39, 9},	{0x61, 10},	{0x4B, 10},	{0x72, 11},	{0x5B, 11},
	{0x36, 10},	{0x49, 11},	{0x37, 11},	{0x29, 12},	{0x30, 12},	{0x35, 13},	{0x17, 13},	{0x18, 14},
	{0x3A, 9},	{0x1B, 8},	{0x32, 9},	{0x60, 10},	{0x4C, 10},	{0x46, 10},	{0x5D, 11},	{0x54, 11},
	{0x4D, 11},	{0x3A, 11},	{0x4F, 12},	{0x1D, 11},	{0x4A, 13},	{0x31, 13},	{0x29, 14},	{0x11, 14},
	{0x2F, 9},	{0x2D, 9},	{0x4E, 10},	{0x4A, 10},	{0x73, 11},	{0x5E, 11},	{0x5A, 11},	{0x4F, 11},
	{0x45, 11},	{0x53, 12},	{0x47, 12},	{0x32, 12},	{0x3B, 13},	{0x26, 13},	{0x24, 14},	{0x0F, 14},
	{0x48, 10},	{0x22, 9},	{0x38, 10},	{0x5F, 11},	{0x5C, 11},	{0x55, 11},	{0x5B, 12},	{0x5A, 12},
	{0x56, 12},	{0x49, 12},	{0x4D, 13},	{0x41, 13},	{0x33, 13},	{0x2C, 14},	{0x2B, 16},	{0x2A, 16},
	{0x2B, 9},	{0x14, 8},	{0x1E, 9},	{0x2C, 10},	{0x37, 10},	{0x4E, 11},	{0x48, 11},	{0x57, 12},
	{0x4E, 12},	{0x3D, 12},	{0x2E, 12},	{0x36, 13},	{0x25, 13},	{0x1E, 14},	{0x14, 15},	{0x10, 15},
	{0x35, 10},	{0x19, 9},	{0x29, 10},	{0x25, 10},	{0x2C, 11},	{0x3B, 11},	{0x36, 11},	{0x51, 13},
	{0x42, 12},	{0x4C, 13},	{0x39, 13},	{0x36, 14},	{0x25, 14},	{0x12, 14},	{0x27, 16},	{0x0B, 15},
	{0x23, 10},	{0x21, 10},	{0x1F, 10},	{0x39, 11},	{0x2A, 11},	{0x52, 12},	{0x48, 12},	{0x50, 13},
	{0x2F, 12},	{0x3A, 13},	{0x37, 14},	{0x15, 13},	{0x16, 14},	{0x1A, 15},	{0x26, 16},	{0x16, 17},
	{0x35, 11},	{0x19, 10},	{0x17, 10},	{0x26, 11},	{0x46, 12},	{0x3C, 12},	{0x33, 12},	{0x24, 12},
	{0x37, 13},	{0x1A, 13},	{0x22, 13},	{0x17, 14},	{0x1B, 15},	{0x0E, 15},	{0x09, 15},	{0x07, 16},
	{0x22, 11},	{0x20, 11},	{0x1C, 11},	{0x27, 12},	{0x31, 12},	{0x4B, 13},	{0x1E, 12},	{0x34, 13},
	{0x30, 14},	{0x28, 14},	{0x34, 15},	{0x1C, 15},	{0x12, 15},	{0x11, 16},	{0x09, 16},	{0x05, 16},
	{0x2D, 12},	{0x15, 11},	{0x22, 12},	{0x40, 13},	{0x38, 13},	{0x32, 13},	{0x31, 14},	{0x2D, 14},
	{0x1F, 14},	{0x13, 14},	{0x0C, 14},	{0x0F, 15},	{0x0A, 16},	{0x07, 15},	{0x06, 16},	{0x03, 16},
	{0x30, 13},	{0x17, 12},	{0x14, 12},	{0x27, 13},	{0x24, 13},	{0x23, 13},	{0x35, 15},	{0x15, 14},
	{0x10, 14},	{0x17, 17},	{0x0D, 15},	{0x0A, 15},	{0x06, 15},	{0x01, 17},	{0x04, 16},	{0x02, 16},
	{0x10, 12},	{0x0F, 12},	{0x11, 13},	{0x1B, 14},	{0x19, 14},	{0x14, 14},	{0x1D, 15},	{0x0B, 14},
	{0x11, 15},	{0x0C, 15},	{0x10, 16},	{0x08, 16},	{0x01, 19},	{0x01, 18},	{0x00, 19},	{0x01, 16}
};

const byte Huffman::bigLookup15[256][2] = {
	{0x07, 3},	{0x0C, 4},	{0x12, 5},	{0x35, 7},	{0x2F, 7},	{0x4C, 8},	{0x7C, 9},	{0x6C, 9},
	{0x59, 9},	{0x7B, 10},	{0x6C, 10},	{0x77, 11},	{0x6B, 11},	{0x51, 11},	{0x7A, 12},	{0x3F, 13},
	{0x0D, 4},	{0x05, 3},	{0x10, 5},	{0x1B, 6},	{0x2E, 7},	{0x24, 7},	{0x3D, 8},	{0x33, 8},
	{0x2A, 8},	{0x46, 9},	{0x34, 9},	{0x53, 10},	{0x41, 10},	{0x29, 10},	{0x3B, 11},	{0x24, 11},
	{0x13, 5},	{0x11, 5},	{0x0F, 5},	{0x18, 6},	{0x29, 7},	{0x22, 7},	{0x3B, 8},	{0x30, 8},
	{0x28, 8},	{0x40, 9},	{0x32, 9},	{0x4E, 10},	{0x3E, 10},	{0x50, 11},	{0x38, 11},	{0x21, 11},
	{0x1D, 6},	{0x1C, 6},	{0x19, 6},	{0x2B, 7},	{0x27, 7},	{0x3F, 8},	{0x37, 8},	{0x5D, 9},
	{0x4C, 9},	{0x3B, 9},	{0x5D, 10},	{0x48, 10},	{0x36, 10},	{0x4B, 11},	{0x32, 11},	{0x1D, 11},
	{0x34, 7},	{0x16, 6},	{0x2A, 7},	{0x28, 7},	{0x43, 8},	{0x39, 8},	{0x5F, 9},	{0x4F, 9},
	{0x48, 9},	{0x39, 9},	{0x59, 10},	{0x45, 10},	{0x31, 10},	{0x42, 11},	{0x2E, 11},	{0x1B, 11},
	{0x4D, 8},	{0x25, 7},	{0x23, 7},	{0x42, 8},	{0x3A, 8},	{0x34, 8},	{0x5B, 9},	{0x4A, 9},
	{0x3E, 9},	{0x30, 9},	{0x4F, 10},	{0x3F, 10},	{0x5A, 11},	{0x3E, 11},	{0x28, 11},	{0x26, 12},
	{0x7D, 9},	{0x20, 7},	{0x3C, 8},	{0x38, 8},	{0x32, 8},	{0x5C, 9},	{0x4E, 9},	{0x41, 9},
	{0x37, 9},	{0x57, 10},	{0x47, 10},	{0x33, 10},	{0x49, 11},	{0x33, 11},	{0x46, 12},	{0x1E, 12},
	{0x6D, 9},	{0x35, 8},	{0x31, 8},	{0x5E, 9},	{0x58, 9},	{0x4B, 9},	{0x42, 9},	{0x7A, 10},
	{0x5B, 10},	{0x49, 10},	{0x38, 10},	{0x2A, 10},	{0x40, 11},	{0x2C, 11},	{0x15, 11},	{0x19, 12},
	{0x5A, 9},	{0x2B, 8},	{0x29, 8},	{0x4D, 9},	{0x49, 9},	{0x3F, 9},	{0x38, 9},	{0x5C, 10},
	{0x4D, 10},	{0x42, 10},	{0x2F, 10},	{0x43, 11},	{0x30, 11},	{0x35, 12},	{0x24, 12},	{0x14, 12},
	{0x47, 9},	{0x22, 8},	{0x43, 9},	{0x3C, 9},	{0x3A, 9},	{0x31, 9},	{0x58, 10},	{0x4C, 10},
	{0x43, 10},	{0x6A, 11},	{0x47, 11},	{0x36, 11},	{0x26, 11},	{0x27, 12},	{0x17, 12},	{0x0F, 12},
	{0x6D, 10},	{0x35, 9},	{0x33, 9},	{0x2F, 9},	{0x5A, 10},	{0x52, 10},	{0x3A, 10},	{0x39, 10},
	{0x30, 10},	{0x48, 11},	{0x39, 11},	{0x29, 11},	{0x17, 11},	{0x1B, 12},	{0x3E, 13},	{0x09, 12},
	{0x56, 10},	{0x2A, 9},	{0x28, 9},	{0x25, 9},	{0x46, 10},	{0x40, 10},	{0x34, 10},	{0x2B, 10},
	{0x46, 11},	{0x37, 11},	{0x2A, 11},	{0x19, 11},	{0x1D, 12},	{0x12, 12},	{0x0B, 12},	{0x0B, 13},
	{0x76, 11},	{0x44, 10},	{0x1E, 9},	{0x37, 10},	{0x32, 10},	{0x2E, 10},	{0x4A, 11},	{0x41, 11},
	{0x31, 11},	{0x27, 11},	{0x18, 11},	{0x10, 11},	{0x16, 12},	{0x0D, 12},	{0x0E, 13},	{0x07, 13},
	{0x5B, 11},	{0x2C, 10},	{0x27, 10},	{0x26, 10},	{0x22, 10},	{0x3F, 11},	{0x34, 11},	{0x2D, 11},
	{0x1F, 11},	{0x34, 12},	{0x1C, 12},	{0x13, 12},	{0x0E, 12},	{0x08, 12},	{0x09, 13},	{0x03, 13},
	{0x7B, 12},	{0x3C, 11},	{0x3A, 11},	{0x35, 11},	{0x2F, 11},	{0x2B, 11},	{0x20, 11},	{0x16, 11},
	{0x25, 12},	{0x18, 12},	{0x11, 12},	{0x0C, 12},	{0x0F, 13},	{0x0A, 13},	{0x02, 12},	{0x01, 13},
	{0x47, 12},	{0x25, 11},	{0x22, 11},	{0x1E, 11},	{0x1C, 11},	{0x14, 11},	{0x11, 11},	{0x1A, 12},
	{0x15, 12},	{0x10, 12},	{0x0A, 12},	{0x06, 12},	{0x08, 13},	{0x06, 13},	{0x02, 13},	{0x00, 13}
};

